import { AudioClip, AudioSource, assetManager } from 'cc';
import { Dictionary } from '../../../../wing/assets/src';
import { LoadItem } from '../declarations';
import { app } from '../application';

/**
 * - 作者: DoooReyn
 * - 日期: 2023.10.31
 * - 名称: 音乐播放组件
 */
export class AudioBgm extends AudioSource {
    /** 缓存 */
    private __cache: Dictionary<AudioClip>;

    constructor() {
        super();
        this.__cache = new Dictionary();
    }

    /**
     * 加载音乐
     * @param options 选项
     * @param options.loop 是否需要循环（默认循环）
     * @param options.cache 是否需要缓存（默认缓存）
     */
    async load(options: LoadItem<AudioClip> & { loop?: boolean; cache?: boolean }) {
        options.cache ??= true;
        options.loop ??= true;
        options.bundle ??= 'resources';

        const clip = this.__cache.fetch(options.path) || (await app.resLoader.loadOne(options));
        if (clip) {
            // 如果和之前是同一份资源，则跳过
            if (this.clip && this.clip === clip && this.playing) return;

            // 添加资源路径标记
            (clip as any)['__path__'] ??= options.path;

            // 添加缓存
            if (options.cache) {
                this.__cache.add(options.path, clip);
            }

            // 停止当前音乐
            if (this.playing) this.stop();

            // 如果上一份资源不在缓存中，则需要释放
            if (this.clip && this.clip !== clip && !this.__cache.has((this.clip as any)['__path__'])) {
                assetManager.releaseAsset(this.clip);
            }

            // 播放
            this.clip = clip;
            this.loop = options.loop;
            this.play();
        }
    }

    /** 释放资源 */
    release() {
        this.stop();
        this.__cache.each((_, clip) => assetManager.releaseAsset(clip));
        this.__cache.clear();
    }
}
